package cn.green.core.model;

import cn.green.core.components.field.FieldTypeCom;
import cn.green.core.components.store.field.FieldTypeStore;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wang.yishu
 * @version 1.0
 * @className QCondition
 * @description 查询条件组件
 * @date 2024/12/27 11:30
 */
@Data
public class QCondition implements Serializable {
    /**
     * 枚举：条件类型
     */
    public enum ConditionType {
        //相等
        EQ,
        //范围
        RANGE,
        //模糊
        LIKE
    }
    //该查询条件所属的表
    private QTable conditionTable;
    //该查询条件所属的属性
    private QField conditionField;
    //查询条件类型
    protected ConditionType type;
    //查询条件数值
    protected List<Object> values;
    //该查询条件的取值key
    protected String valueKey;

    public String getValueKey() {
        if (valueKey == null || valueKey.isEmpty()) {
            return this.conditionField.getFieldName();
        } else {
            return valueKey;
        }
    }

    //内部类：比较器
    public static class Compare {
        //比较之间
        public static int compareBetween(Object a, Object b) {
            if (a != null && b != null) {
                if (a instanceof Date && b instanceof Date) {
                    return ((Date) a).compareTo((Date) b);
                } else if (a instanceof Number && b instanceof Number) {
                    return Double.compare(((Number) a).doubleValue(), ((Number) b).doubleValue());
                } else if (a instanceof String && b instanceof String) {
                    return a.toString().compareTo(b.toString());
                }
            }
            return 0;
        }

        //比较
        public static boolean compare(QTable table, JSONObject item, JSONObject param) {
            boolean result = true;
            List<QCondition> conditions = new ArrayList<>();
            table.getFields().forEach((f) -> {
                String fieldType = f.getFieldType();
                if (fieldType != null && !fieldType.isEmpty()) {
                    FieldTypeCom fieldTypeCom = FieldTypeStore.get(fieldType);
                    List<QCondition> fConditions = fieldTypeCom.conditions(f, param);
                    conditions.addAll(fConditions);
                }
            });
            if (!conditions.isEmpty()) {
                for (QCondition condition : conditions) {
                    //todo 这里可能有问题
                    Object vvl = item.get(condition.getValueKey());
                    ConditionType type = condition.getType();
                    List<Object> values = condition.getValues();
                    if (values == null || values.isEmpty()) {
                        continue;
                    }
                    switch (type) {
                        case EQ:
                            Object vbj = values.get(0);
                            result = result && vvl != null && vvl.equals(vbj);
                            break;
                        case RANGE:
                            Object vbjLeft = values.get(0);
                            result = result && vvl != null && compareBetween(vbjLeft, vvl) >= 0;
                            if (values.size() > 1) {
                                Object vbjRight = values.get(1);
                                result = result && compareBetween(vvl, vbjRight) >= 0;
                            }
                            break;
                        case LIKE:
                            Object vStr = values.get(0);
                            result = result && vvl != null && compareBetween(vStr, vvl) == 0;
                            break;
                        default:break;
                    }
                }
            }
            return result;
        }
    }


}
